package com.dcits.helper;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import lombok.Builder;
import lombok.Data;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MybatisPlusGeneratorHelper {
    private MybatisPlusGeneratorHelper() {
    }

    @Data
    @Builder
    public static class Param {
        /**
         * 子工程名称
         */
        private String baseSubModuleName;
        /**
         * 子工程报名
         */
        private String baseSubModulePackage;
        /**
         * 工程代码基础包package定义
         */
        private String basePackage;

        private String dbUrl;
        private String dbUsername;
        private String dbPassword;

        private List<String> tableInclude;
        /**
         * 可选的表前缀过滤
         */
        private List<String> tablePrefix;
    }

    public static void generatorCode(Param param) {
        //
        final String projectPath = System.getProperty("user.dir") + param.baseSubModuleName;
        final String baseSubPackage = param.baseSubModulePackage;
        // 数据源配置
        FastAutoGenerator.create(param.getDbUrl(), param.dbUsername, param.dbPassword).globalConfig(builder -> {
                    final String pathJava = "src/main/java";
                    builder.author(System.getProperty("user.name"))        // 设置作者
                            .enableSwagger()        // 开启 swagger 模式 默认值:false
                            .disableOpenDir()       // 禁止打开输出目录 默认值:true
                            .commentDate("yyyy-MM-dd") // 注释日期
                            .dateType(DateType.ONLY_DATE)   //定义生成的实体类中日期类型 DateType.ONLY_DATE 默认值: DateType.TIME_PACK
                            .outputDir(projectPath + pathJava); // 指定输出目录
                }).packageConfig(builder -> {
                    final String pathMapperXml = "src/main/resources/mapper";
                    builder.parent(baseSubPackage) // 父包模块名
                            .controller("controller")   //Controller 包名 默认值:controller
                            .entity("entity")           //Entity 包名 默认值:entity
                            .service("service")         //Service 包名 默认值:service
                            .serviceImpl("service.impl").mapper("mapper")           //Mapper 包名 默认值:mapper
                            .pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + pathMapperXml)); // 设置mapperXml生成路径
                    //默认存放在mapper的xml下
                }).injectionConfig(builder -> {
                    final String pathJava = "src/main/java";

                    final String dtoPackage = baseSubPackage + ".dto";
                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("dtoPackageIn", dtoPackage + ".in");
                    customMap.put("dtoPackageOut", dtoPackage + ".out");
                    customMap.put("basePackage", param.basePackage);
                    builder.customMap(customMap);
                    // 定义入参
                    builder.customFile(builder2 -> builder2.fileName("In.java").templatePath("templates/dtoIn.java.ftl") // 模板路径
                            .filePath(projectPath + pathJava) // 输出根目录
                            .packageName(dtoPackage + ".in") // 实际包路径
                            .enableFileOverride());
                    // 定义出参
                    builder.customFile(builder2 -> builder2.fileName("Out.java").templatePath("templates/dtoOut.java.ftl") // 模板路径
                            .filePath(projectPath + pathJava) // 输出根目录
                            .packageName(dtoPackage + ".out") // 实际包路径
                            .enableFileOverride());
                })


                .strategyConfig(builder ->
                                builder.addInclude(param.tableInclude) // 设置需要生成的表名 可边长参数“user”, “user1”
                                        .addTablePrefix(param.tablePrefix) // 设置过滤表前缀
                                        .serviceBuilder()//service策略配置
                                        .formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").entityBuilder()// 实体类策略配置
//                            .formatFileName("%sEntity") //表实体统一加Entity
                                        .idType(IdType.ASSIGN_ID)//主键策略  雪花算法自动生成的id
                                        .addTableFills(new Column("create_time", FieldFill.INSERT)) // 自动填充配置
                                        .addTableFills(new Property("update_time", FieldFill.INSERT_UPDATE)).enableLombok() //开启lombok
//                            .logicDeleteColumnName("deleted")// 说明逻辑删除是哪个字段
                                        .enableTableFieldAnnotation()// 属性加上注解说明
                                        .controllerBuilder() //controller 策略配置
                                        .formatFileName("%sController").enableRestStyle() // 开启RestController注解
                                        .mapperBuilder()// mapper策略配置
                                        .formatMapperFileName("%sMapper").enableMapperAnnotation()//@mapper注解开启
                                        .formatXmlFileName("%sMapper").enableBaseColumnList()
                )

                // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .templateEngine(new FreemarkerTemplateEngine()).execute();
    }
}
